/***************************************************************************************************
* File Name:	main.c
* Description:	第8章实例训练
* Reference book:《Linux应用与开发典型实例精讲》邱铁，于玉龙，徐子川 编著，清华大学出版社.2010.5
* E_mail: openlinux21@gmail.com
*
****************************************************************************************************/

#include "mysemop.h"
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>

int root_sem_id = 0;
int chopsticks_sem_id[5];

int main(int argc, char argv[])
{
	pid_t pid;

	pid_t chldpid[5];

	char ch;
	int i = 0;

	int room_sem_id = CreateSem(4);
	for (i = 0; i < 5; i++) {
		chopsticks_sem_id[i] = CreateSem(1);
	}

	for (i = 0; i < 5; i++) {
		pid = fork();
		if (pid < 0) {
			fprintf(stderr, "When fork philosopher %d Failed!\n", i);
			exit(-1);
		}
		if (pid == 0) {
			while (1) {
				printf("Philopher %d is thinking,No disterb!\n", i);
				sleep(1);
				// 奇数编号的哲学家先拿左边的筷子，偶数编号的先拿右边的筷子
				if (i % 2 == 0) {
					Psem(chopsticks_sem_id[(i + 1) % 5]);
					printf("Philosopher %d picks up right chopstick first.\n", i);
					Psem(chopsticks_sem_id[i]);
					printf("Philosopher %d then picks up leftchopstick.\n", i);

				}
				else {
					Psem(chopsticks_sem_id[i]);
					printf("Philosopher %d picks up left chopstick first.\n", i);
					Psem(chopsticks_sem_id[(i + 1) % 5]);
					printf("Philosopher %d then picks up right chopstick.\n", i);

				}

				printf("Philopher %d begins to eat!\n", i);
				sleep(5 - i);

				printf("Philopher %d ends to eat!\n", i);
				Vsem(chopsticks_sem_id[(i + 1) % 5]);

				printf("Philopher %d put down right chopstick\n", i);
				Vsem(chopsticks_sem_id[i]);

				printf("Philopher %d put down left chopstick\n", i);
				Vsem(room_sem_id);

				printf("Philopher %d left the room!\n", i);
				printf("Philopher %d begins thinking!\n", i);
				sleep(1);
			}
		}
		else
		{

			chldpid[i] = pid;

		}
	}

	do
	{

		ch = getchar();

		if (ch == 'q')

		{

			for (i = 0; i < 5; i++)

				kill(chldpid[i], SIGTERM);

		}

	} while (ch != 'q');
}
